package club.kingyin.kyblogprouser.controller;



import club.kingyin.commons.constant.AuthorizeConstant;
import club.kingyin.commons.enums.BlogEnum;
import club.kingyin.commons.response.Result;
import club.kingyin.easycache.annotation.EasyCache;
import club.kingyin.easycache.core.impl.AbstractEasyCacheKey;
import club.kingyin.easycache.core.impl.DefaultEasyCache;
import club.kingyin.kyblogprouser.dao.MessageDao;
import club.kingyin.kyblogprouser.entity.MessagePram;
import club.kingyin.kyblogprouser.entity.MessagePush;
import club.kingyin.kyblogprouser.entity.Users;
import club.kingyin.kyblogprouser.service.UserService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import club.kingyin.commons.entity.user.Message;
import club.kingyin.kyblogprouser.service.MessageService;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * (Message)表控制层
 *
 * @author makejava
 * @since 2022-01-20 15:04:02
 */
@RestController
@RequestMapping("message")
public class MessageController {
    /**
     * 服务对象
     */
    @Resource
    private MessageService messageService;

    @Resource
    private MessageDao messageDao;

    @Resource
    private UserService userService;

    @Resource
    private DefaultEasyCache defaultEasyCache;

    /**
     * 分页查询所有数据
     *
     * @param pram 分页对象
     * @return 所有数据
     */
    @PostMapping("/all")
    public Result selectAll(@RequestHeader(AuthorizeConstant.ROLE) String role,
            @RequestBody MessagePram pram) throws UnsupportedEncodingException {
        switch (Objects.requireNonNull(BlogEnum.deBlogEnum(URLDecoder.decode(role, "UTF8")))) {
            case ADMIN:
            case ROOT:
                return Result.success(this.messageService.page(pram.getPage(), new LambdaQueryWrapper<>(pram.getMessage()).orderByDesc(Message::getTimestamp)));
            default: return Result.failR("无操作权限");
        }
    }

    /**
     * 通过主键查询单条数据
     *
     * @param id 主键
     * @return 单条数据
     */
    @EasyCache(prams = "id",module = "ky-user")
    @GetMapping("/push")
    public Result selectOne(@RequestParam("id") Serializable id) {
        Message msg = this.messageService.getById(id);
        if (msg == null) {
            msg = new Message();
            msg.setType(BlogEnum.MESSAGE);
            msg.setUserid(0);
            msg.setData("消息不存在");
            msg.setId(-2);
        }
        return Result.success(this.messageService.getById(id));
    }

    /**
     * 新增数据
     *
     * @param message 实体对象
     * @return 新增结果
     */
    @EasyCache(prams = {"message.userid"},delete = {"getMessages"}, module = "ky-user")
    @PostMapping("/save")
    public Result insert(@RequestHeader(AuthorizeConstant.ID) int userid,
                         @RequestBody Message message) {
        if (message.getUserid() == -1) {
            message.setUserid(userid* message.getUserid());
        }
        if (Math.abs(message.getUserid()) == message.getObjectid())
            return Result.success(null);
        message.setTimestamp(System.currentTimeMillis());
        message.setStatus(BlogEnum.UNREAD);
        return Result.success(this.messageService.save(message));
    }

    @EasyCache(prams = {"message.userid"},delete = {"getMessages"}, module = "ky-user")
    @PostMapping("/notice")
    public Result insert(@RequestBody Message message) {
        if (Math.abs(message.getUserid()) == message.getObjectid())
            return Result.success(null);
        message.setTimestamp(System.currentTimeMillis());
        message.setStatus(BlogEnum.UNREAD);
        return Result.success(this.messageService.save(message));
    }

    // 删除的更多缓存
    @PostMapping("/push")
    public Result push(@RequestHeader(AuthorizeConstant.AVATAR) String avater,
                       @RequestBody MessagePush message) throws UnsupportedEncodingException {
        String pattern = "^(0|[2-9][0-9]{6})+(,(0|[2-9][0-9]{6})+)*,?$";

        if (!Pattern.matches(pattern,message.getIds())) {
            return Result.failR("ID有误");
        }
        String[] split = message.getIds().split(",");
        Set<String> ids = Arrays.stream(split).collect(Collectors.toSet());
        int id;
        Message msg = new Message();
        msg.setData(message.getData());
        msg.setTimestamp(System.currentTimeMillis());
        msg.setHtml(message.getHtml());
        msg.setType(message.getStatus());
        msg.setStatus(BlogEnum.UNREAD);
        msg.setObjectid(message.getObjectid());
        msg.setAvatar(URLDecoder.decode(avater, "UTF8"));
        Set<Integer> success = new HashSet<>();
        Set<Integer> failed = new HashSet<>();
        for (String i : ids) {
            id = Integer.parseInt(i);
            if(id != 0 && userService.getById(id) == null) {
                failed.add(id);
                continue;
            }
            msg.setUserid(id);
            if (messageService.save(msg)) {
                success.add(id);
                // 删除缓存
                defaultEasyCache.remove(new AbstractEasyCacheKey() {
                    @Override
                    protected void setPrams() {
                        prams.put("userid",msg.getUserid());
                    }
                    @Override
                    public boolean equals(String key) {
                        // 0 删除全部
                        return msg.getUserid() == 0 || super.equals(key);
                    }
                },"ky-user","getMessages");
            } else {
                failed.add(id);
            }
        }
        Map<String,Set<Integer>> res = new HashMap<>();
        res.put("success",success);
        res.put("failed",failed);
        return Result.success(res);
    }

    @EasyCache(prams = {"userid","page.current","page.size"}, module = "ky-user")
    @PostMapping("/list")
    public Result getMessages(@RequestHeader(AuthorizeConstant.ID) int userid, Page<Message> page) {
        LambdaQueryWrapper<Message> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.in(Message::getUserid,userid,0);
        queryWrapper.orderByDesc(Message::getTimestamp).orderByDesc(Message::getStatus);
        return Result.success(messageDao.selectPage(page, queryWrapper));
    }

    @EasyCache(prams = {"userid"},delete = {"getMessages"}, module = "ky-user")
    @EasyCache(prams = {"id"},delete = {"selectOne"}, module = "ky-user")
    @GetMapping("/delete")
    public Result remove(@RequestHeader(AuthorizeConstant.ID) int userid,
                         @RequestHeader(AuthorizeConstant.ROLE) String role,
                         @RequestParam("id") int id) throws UnsupportedEncodingException {
        LambdaQueryWrapper<Message> queryWrapper = Wrappers.lambdaQuery();
        switch (Objects.requireNonNull(BlogEnum.deBlogEnum(URLDecoder.decode(role, "UTF8")))) {
            case ADMIN:
            case ROOT:
                queryWrapper.eq(Message::getId,id);
                break;
            default: queryWrapper.eq(Message::getUserid,userid);
                if (id != -1) {
                    queryWrapper.eq(Message::getId,id);
                }
        }
        return messageDao.delete(queryWrapper)>0?Result.infoN("已删除"):Result.infoN("没有了");
    }

    @PostMapping("/delete/failed")
    public Result removeByAsyncFailedIds(@RequestBody Users messageIds) {
        LambdaQueryWrapper<Message> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.likeLeft(Message::getData,"请前往重新保存").in(Message::getObjectid,messageIds.getIds());
        return messageDao.delete(queryWrapper)>0?Result.success("删除成功"):Result.failR("删除失败");
    }

    @EasyCache(prams = {"userid"},delete = {"getMessages"}, module = "ky-user")
    @GetMapping("/read")
    public Result read(@RequestHeader(AuthorizeConstant.ID) int userid, @RequestParam("id") int id) {
        LambdaUpdateWrapper<Message> queryWrapper = Wrappers.lambdaUpdate();
        queryWrapper.eq(Message::getUserid,userid).set(Message::getStatus, BlogEnum.READ);
        if (id != -1) {
            queryWrapper.eq(Message::getId,id);
        }
        return messageDao.update(null,queryWrapper)>0?Result.infoN("已读"):Result.infoN("没有了");
    }

//    /**
//     * 修改数据
//     *
//     * @param message 实体对象
//     * @return 修改结果
//     */
//    @PutMapping
//    public Result update(@RequestBody Message message) {
//        return Result.success(this.messageService.updateById(message));
//    }
//
//    /**
//     * 删除数据
//     *
//     * @param idList 主键结合
//     * @return 删除结果
//     */
//    @DeleteMapping
//    public Result delete(@RequestParam("idList") List<Long> idList) {
//        return Result.success(this.messageService.removeByIds(idList));
//    }
}

